<?php

namespace Huang\PhpPersonalTools;

use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\LabelAlignment;
use Endroid\QrCode\QrCode;

class QrcodeService
{
    protected $_qr;
    protected $_encoding = 'UTF-8';              // 编码类型
    protected $_size = 300;                  // 二维码大小
    protected $_logo = false;                // 是否需要带logo的二维码
    protected $_logo_url = '';                   // logo图片路径
    protected $_logo_size = 80;                   // logo大小
    protected $_title = false;                // 是否需要二维码title
    protected $_title_content = '';                   // title内容
    protected $_generate = 'display';            // display-直接显示  writefile-写入文件
    protected $_file_name = './';                 // 写入文件路径
    const MARGIN = 10;                        // 二维码内容相对于整张图片的外边距
    const WRITE_NAME = 'png';                     // 写入文件的后缀名
    const FOREGROUND_COLOR = ['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0];          // 前景色
    const BACKGROUND_COLOR = ['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0];    // 背景色

    public function __construct($config)
    {
        isset($config['generate']) && $this->_generate = $config['generate'];
        isset($config['encoding']) && $this->_encoding = $config['encoding'];
        isset($config['size']) && $this->_size = $config['size'];
        isset($config['logo']) && $this->_logo = $config['logo'];
        isset($config['logo_url']) && $this->_logo_url = $config['logo_url'];
        isset($config['logo_size']) && $this->_logo_size = $config['logo_size'];
        isset($config['title']) && $this->_title = $config['title'];
        isset($config['title_content']) && $this->_title_content = $config['title_content'];
        isset($config['file_name']) && $this->_file_name = $config['file_name'];
    }

    /**
     * 生成二维码
     * @param $content //需要写入的内容
     * @param $file  文件名
     * @return array | page input
     */
    public function createServer($content, $file)
    {
        $this->_qr = new QrCode($content);
        $this->_qr->setSize($this->_size);
        $this->_qr->setWriterByName(self::WRITE_NAME);
        $this->_qr->setMargin(self::MARGIN);
        $this->_qr->setEncoding($this->_encoding);
        $this->_qr->setErrorCorrectionLevel(new ErrorCorrectionLevel(ErrorCorrectionLevel::HIGH));   // 容错率
        $this->_qr->setForegroundColor(self::FOREGROUND_COLOR);
        $this->_qr->setBackgroundColor(self::BACKGROUND_COLOR);
        // 是否需要title
        if ($this->_title) {
            $this->_qr->setLabel($this->_title_content, 16, null, LabelAlignment::CENTER);
        }
        // 是否需要logo

        if ($this->_logo) {
            $this->_qr->setLogoPath($this->_logo_url);
            $this->_qr->setLogoWidth($this->_logo_size);
        }

        $this->_qr->setValidateResult(false);

        if ($this->_generate == 'display') {
            // 展示二维码
            // 前端调用 例：<img src="https://localhost/qr.php?url=base64_url_string">
            header('Content-Type: ' . $this->_qr->getContentType());
            return $this->_qr->writeString();
        } else if ($this->_generate == 'writefile') {
            // 写入文件
            $file_name = $this->_file_name;
            return $this->generateImg($file_name, $file);
        } else {
            return ['success' => false, 'message' => 'the generate type not found', 'data' => ''];
        }
    }

    /**
     * 生成文件
     * @param $file_name //目录文件 例: /tmp
     * @param $file  文件名
     * @return array
     */
    public function generateImg($file_name, $file)
    {
        $file_path = $file_name . DIRECTORY_SEPARATOR . $file . '.' . self::WRITE_NAME;
        if (!file_exists($file_name)) {
            mkdir($file_name, 0777, true);
        }
        try {
            if (is_file($file_path)) {
                return ['code' => true, 'data' => $file_path];
            } else {
                $this->_qr->writeFile($file_path);
                $data = [
                    'url' => $file_path,
                    'ext' => self::WRITE_NAME,
                ];
                return ['code' => true, 'message' => 'write qrimg success', 'data' => $file_path];
            }

        } catch (\Exception $e) {
            return ['code' => false, 'message' => $e->getMessage(), 'data' => ''];
        }
    }

    public static function newDir($dir, $preDir = '')
    {
        $parts = explode('/', $dir);
        $dir = $preDir;
        foreach ($parts as $part)
            if (!is_dir($dir .= "/$part")) mkdir($dir, 0755);
        return $dir;
    }

    /**
     * @description
     * @param $backgroundImagePath  背景图
     * @param $qrCodeImageUrl       二维码图片 可以是链接
     * @param $outputImagePath      保存的文件名+路径
     * @param int $qrCodeSize
     * @return bool
     */
    public static function createPosterWithQRCode($backgroundImagePath, $qrCodeImageUrl, $outputImagePath, $qrCodeSize = 200)
    {
        try {

            /* 如果是tp5或tp6  $outputImagePath 记得改为绝对路径
              $saveppath = ROOT_PATH . "public/";
            $outputImagePath = $saveppath.$outputImagePath;*/
            if (!file_exists($outputImagePath)) {
                self::newDir(dirname($outputImagePath));
                //mkdir(dirname($outputImagePath),0755,true);
            }
            $extension = pathinfo($backgroundImagePath, PATHINFO_EXTENSION);
            if (in_array($extension, ['jpg', 'jpeg'])) {
                $background = imagecreatefromjpeg($backgroundImagePath);
            } elseif ($extension === 'png') {
                $background = imagecreatefrompng($backgroundImagePath);
            } else {
                throw new Exception('不支持的文件格式');
                // 处理不支持的文件格式
            }
            // 加载背景图片
//           $background = imagecreatefrompng($backgroundImagePath); // 假设背景图片是JPEG格式


            // 从二维码图片的URL加载图片
            list($qrCodeWidth, $qrCodeHeight, $qrCodeType, $qrCodeAttr) = getimagesize($qrCodeImageUrl);
            switch ($qrCodeType) {
                case IMAGETYPE_PNG:
                    $qrCodeImage = imagecreatefrompng($qrCodeImageUrl);
                    break;
                case IMAGETYPE_JPEG:
                    $qrCodeImage = imagecreatefromjpeg($qrCodeImageUrl);
                    break;
                // 可以添加更多图片类型的处理
                default:
                    // 错误处理：不支持的图片类型
                    return false;
            }

            // 设定二维码在海报上的位置（例如：右下角）并计算缩放比例
            $positionX = imagesx($background) - $qrCodeSize - 10; // 10为内边距
            $positionY = imagesy($background) - $qrCodeSize - 10;

            // 计算缩放比例，这里我们假设宽度和高度都缩放为$qrCodeSize
            $scaleWidth = $qrCodeSize;
            $scaleHeight = $qrCodeSize;

            // 创建一个新的缩放后的二维码图片
            $scaledQRCodeImage = imagecreatetruecolor($scaleWidth, $scaleHeight);

            // 缩放二维码图片
            imagecopyresampled(
                $scaledQRCodeImage, // 目标图片
                $qrCodeImage, // 源图片
                0, 0, // 目标图片上的开始位置
                0, 0, // 源图片上的开始位置
                $scaleWidth, $scaleHeight, // 目标图片的宽高
                $qrCodeWidth, $qrCodeHeight // 源图片的宽高
            );

            // 合并图片
            imagecopy($background, $scaledQRCodeImage, $positionX, $positionY, 0, 0, $scaleWidth, $scaleHeight);

            // 保存合并后的图片
            imagejpeg($background, $outputImagePath);

            // 清理资源
            imagedestroy($background);
            imagedestroy($qrCodeImage);
            imagedestroy($scaledQRCodeImage);

            return $outputImagePath; // 成功返回true
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }
    }
}
